package hu.bme.aut.consulttime.client.components;

import java.util.Date;
import java.util.List;

import hu.bme.aut.consulttime.client.EvaluationService;
import hu.bme.aut.consulttime.client.EvaluationServiceAsync;
import hu.bme.aut.consulttime.client.LogService;
import hu.bme.aut.consulttime.client.LogServiceAsync;
import hu.bme.aut.consulttime.client.ProjectService;
import hu.bme.aut.consulttime.client.ProjectServiceAsync;
import hu.bme.aut.consulttime.client.TeamService;
import hu.bme.aut.consulttime.client.TeamServiceAsync;
import hu.bme.aut.consulttime.client.ToDoService;
import hu.bme.aut.consulttime.client.ToDoServiceAsync;
import hu.bme.aut.consulttime.entitydtos.EvaluationDTO;
import hu.bme.aut.consulttime.entitydtos.LogDTO;
import hu.bme.aut.consulttime.entitydtos.ToDoDTO;
import hu.bme.aut.consulttime.entitydtos.UserDTO;
import hu.bme.aut.consulttime.entitydtos.ProjectDTO;
import hu.bme.aut.consulttime.entitydtos.TeamDTO;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;

public class TutorToDoPage extends Composite {
	private long userId;
	private List<UserDTO> teamMembers;
	private List<UserDTO> projectTutors;
	private long selectedTeamId;
	private long selectedProjectId;
	private long selectedTeamMemberUserId;
	
	
	private VerticalPanel mainPanel;
	private ListBox selectProjectListBox;
	private ListBox selectTeamListBox;
	private ListBox selectTeamMemberListBox;
	private Tree toDoTree;
	
	private TeamServiceAsync teamService = GWT.create(TeamService.class);
	private ProjectServiceAsync projectService = GWT.create(ProjectService.class);
	private ToDoServiceAsync toDoService = GWT.create(ToDoService.class);
	private EvaluationServiceAsync evaluationService = GWT.create(EvaluationService.class);
	private LogServiceAsync logService = GWT.create(LogService.class);
	
	public TutorToDoPage() {
		super();
		
		mainPanel = new VerticalPanel();
		initWidget(mainPanel);
		mainPanel.setSize("100%", "100%");
		
		HorizontalPanel horizontalPanel = new HorizontalPanel();
		mainPanel.add(horizontalPanel);
		mainPanel.setCellVerticalAlignment(horizontalPanel, HasVerticalAlignment.ALIGN_MIDDLE);
		mainPanel.setCellHorizontalAlignment(horizontalPanel, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel.setSize("100%", "30px");
		horizontalPanel.setSpacing(5);
		
		Label lblNewLabel = new Label("Projects:");
		lblNewLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
		horizontalPanel.add(lblNewLabel);
		lblNewLabel.setWidth("70px");
		horizontalPanel.setCellVerticalAlignment(lblNewLabel, HasVerticalAlignment.ALIGN_MIDDLE);
		
		selectProjectListBox = new ListBox();
		horizontalPanel.add(selectProjectListBox);
		horizontalPanel.setCellWidth(selectProjectListBox, "100%");
		selectProjectListBox.setWidth("100%");
		horizontalPanel.setCellVerticalAlignment(selectProjectListBox, HasVerticalAlignment.ALIGN_MIDDLE);
		selectProjectListBox.addItem("Select a project to view it's teams...");
		
		selectProjectListBox.addChangeHandler(new ChangeHandler() {
			
			@Override
			public void onChange(ChangeEvent event) {
				 int selectedIndex = selectProjectListBox.getSelectedIndex();
				 if (selectedIndex != 0) {
					 selectTeamListBox.setEnabled(true);
					 selectedProjectId = Long.valueOf(selectProjectListBox.getValue(selectedIndex));
					 loadProjectTutors(selectedProjectId);
					 loadTeams(selectedProjectId);
				 }
				 else {
					selectTeamListBox.setEnabled(false);
					selectTeamListBox.setSelectedIndex(0);
					selectTeamMemberListBox.setEnabled(false);
					selectTeamMemberListBox.setSelectedIndex(0);
					toDoTree.setVisible(false);
				}
			}
		});
		
		HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
		mainPanel.add(horizontalPanel_2);
		mainPanel.setCellVerticalAlignment(horizontalPanel_2, HasVerticalAlignment.ALIGN_MIDDLE);
		mainPanel.setCellHorizontalAlignment(horizontalPanel_2, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_2.setSize("100%", "30px");
		horizontalPanel_2.setSpacing(5);
		
		Label lblNewLabel_2 = new Label("Teams:");
		lblNewLabel_2.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
		horizontalPanel_2.add(lblNewLabel_2);
		lblNewLabel_2.setWidth("70px");
		horizontalPanel_2.setCellVerticalAlignment(lblNewLabel_2, HasVerticalAlignment.ALIGN_MIDDLE);
		
		selectTeamListBox = new ListBox();
		horizontalPanel_2.add(selectTeamListBox);
		horizontalPanel_2.setCellWidth(selectTeamListBox, "100%");
		selectTeamListBox.setWidth("100%");
		horizontalPanel_2.setCellVerticalAlignment(selectTeamListBox, HasVerticalAlignment.ALIGN_MIDDLE);
		selectTeamListBox.addItem("Select a team to view it's members...");
		selectTeamListBox.setEnabled(false);
		
		selectTeamListBox.addChangeHandler(new ChangeHandler() {
			
			@Override
			public void onChange(ChangeEvent event) {
				 int selectedIndex = selectTeamListBox.getSelectedIndex();
				 if (selectedIndex != 0) {
					 selectTeamMemberListBox.setEnabled(true);
					 selectedTeamId = Long.valueOf(selectTeamListBox.getValue(selectedIndex));
					 loadTeamMembers(selectedTeamId);
				 }
				 else {
					selectTeamMemberListBox.setEnabled(false);
					selectTeamMemberListBox.setSelectedIndex(0);
					toDoTree.setVisible(false);
				}
			}
		});
		
		HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
		mainPanel.add(horizontalPanel_3);
		mainPanel.setCellVerticalAlignment(horizontalPanel_3, HasVerticalAlignment.ALIGN_MIDDLE);
		mainPanel.setCellHorizontalAlignment(horizontalPanel_3, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setSize("100%", "30px");
		horizontalPanel_3.setSpacing(5);
		
		Label lblNewLabel_3 = new Label("Members:");
		lblNewLabel_3.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
		horizontalPanel_3.add(lblNewLabel_3);
		lblNewLabel_3.setWidth("70px");
		horizontalPanel_3.setCellVerticalAlignment(lblNewLabel_3, HasVerticalAlignment.ALIGN_MIDDLE);
		
		selectTeamMemberListBox = new ListBox();
		horizontalPanel_3.add(selectTeamMemberListBox);
		horizontalPanel_3.setCellWidth(selectTeamMemberListBox, "100%");
		selectTeamMemberListBox.setWidth("100%");
		horizontalPanel_3.setCellVerticalAlignment(selectTeamMemberListBox, HasVerticalAlignment.ALIGN_MIDDLE);
		selectTeamMemberListBox.addItem("Select a team member to view his/her to-dos...");
		selectTeamMemberListBox.setEnabled(false);
		
		selectTeamMemberListBox.addChangeHandler(new ChangeHandler() {
			
			@Override
			public void onChange(ChangeEvent event) {
				 int selectedIndex = selectTeamMemberListBox.getSelectedIndex();
				 if (selectedIndex != 0) {
					 toDoTree.setVisible(true);
					 selectedTeamMemberUserId = Long.valueOf(selectTeamMemberListBox.getValue(selectedIndex));
					 loadToDos(selectedTeamMemberUserId);
				 }
				 else {
					toDoTree.setVisible(false);
				}
			}
		});
		
		toDoTree = new Tree();
		toDoTree.setAnimationEnabled(true);
		mainPanel.add(toDoTree);
		toDoTree.setSize("100%", "100%");
		toDoTree.setVisible(false);
		
		toDoTree.addOpenHandler(new OpenHandler<TreeItem>() {
			
			@Override
			public void onOpen(OpenEvent<TreeItem> event) {
			    TreeItem item = (TreeItem)event.getTarget();
			    if (item.getText().equals("Evaluation")) {
			    	loadEvaluation(item);
			    }
			    else if (item.getText().equals("Logs")) {
			    	loadLogs(item);
			    }
			}
		});
	}
	

	public long getUserId() {
		return userId;
	}

	public void setUserId(long userId) {
		this.userId = userId;
	}

	public void loadProjects() {
		selectProjectListBox.clear();
		selectProjectListBox.addItem("Select a project to view it's teams...");
		
		projectService.retrieveProjects(userId, new AsyncCallback<List<ProjectDTO>>() {

			@Override
			public void onSuccess(List<ProjectDTO> result) {
				for (ProjectDTO projectDTO : result) {
					selectProjectListBox.addItem(projectDTO.getTitle() + " (" + projectDTO.getType().toString() + ")", String.valueOf(projectDTO.getProjectId()));
				}
				selectProjectListBox.setSelectedIndex(0);
				selectTeamListBox.setEnabled(false);
				selectTeamListBox.setSelectedIndex(0);
				selectTeamMemberListBox.setEnabled(false);
				selectTeamMemberListBox.setSelectedIndex(0);
				toDoTree.setVisible(false);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});
		
	}
	
	public void loadProjectTutors(long projectId) {
		
		projectService.retrieveTutors(projectId, new AsyncCallback<List<UserDTO>>() {
			
			@Override
			public void onSuccess(List<UserDTO> result) {
				projectTutors = result;
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});
		
	}
	
	public void loadTeams(long projectId) {
		selectTeamListBox.clear();
		selectTeamListBox.addItem("Select a team to view it's members...");
		
		teamService.retrieveTeams(projectId, new AsyncCallback<List<TeamDTO>>() {

			@Override
			public void onSuccess(List<TeamDTO> result) {
				for (TeamDTO teamDTO : result) {
					selectTeamListBox.addItem(teamDTO.getName() + " (" + teamDTO.getSemesterId() + ")", String.valueOf(teamDTO.getTeamId()));
				}
				selectTeamListBox.setSelectedIndex(0);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});
		
	}
	
	public void loadTeamMembers(long teamId) {
		selectTeamMemberListBox.clear();
		selectTeamMemberListBox.addItem("Select a team member to view his/her to-dos...");
		
		teamService.retrieveMembers(teamId, new AsyncCallback<List<UserDTO>>() {
			
			@Override
			public void onSuccess(List<UserDTO> result) {
				teamMembers = result;
				for (UserDTO userDTO : result) {
					selectTeamMemberListBox.addItem(userDTO.getFirstName() + " " + userDTO.getLastName() + " (" + userDTO.getUserName() + ")", String.valueOf(userDTO.getUserId()));
				}
				selectTeamMemberListBox.setSelectedIndex(0);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});
		
	}
	
	private void loadToDos(long studentId) {

		resetToDoTree();
		
		toDoService.retrieveToDosForStudent(studentId, selectedTeamId, new AsyncCallback<List<ToDoDTO>>() {
			
			@Override
			public void onSuccess(List<ToDoDTO> result) {
				
				for (ToDoDTO toDoDTO : result) {
					
					HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
					horizontalPanel_3.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
					TreeItem toDoTreeItem = toDoTree.addItem(horizontalPanel_3);
					horizontalPanel_3.setSize("100%", "20px");
					toDoTreeItem.setWidth("100%");
					
					toDoTreeItem.setUserObject(toDoDTO);
					
					Label lblWeek = new Label(String.valueOf(toDoDTO.getWeek()));
					horizontalPanel_3.add(lblWeek);
					horizontalPanel_3.setCellHorizontalAlignment(lblWeek, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblWeek, "20%");
					
					UserDTO student = null;
					
					for (UserDTO s : teamMembers) {
						if (s.getUserId() == toDoDTO.getStudentId())
							student = s;
					}
					
					Label lblStudent = new Label(student.getFirstName() + " " + student.getLastName() + " (" + student.getUserName() + ")");
					horizontalPanel_3.add(lblStudent);
					horizontalPanel_3.setCellHorizontalAlignment(lblStudent, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblStudent, "20%");
					
					UserDTO tutor = null;
					
					for (UserDTO t : projectTutors) {
						if (t.getUserId() == toDoDTO.getTutorId())
							tutor = t;
					}
					
					Label lblTutor = new Label(tutor.getFirstName() + " " + tutor.getLastName() + " (" + tutor.getUserName() + ")");
					horizontalPanel_3.add(lblTutor);
					horizontalPanel_3.setCellHorizontalAlignment(lblTutor, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblTutor, "20%");
					
					Label lblDate = new Label(toDoDTO.getDate().toString());
					horizontalPanel_3.add(lblDate);
					horizontalPanel_3.setCellHorizontalAlignment(lblDate, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblDate, "20%");
					
					Label lblTitle = new Label(toDoDTO.getTitle());
					horizontalPanel_3.add(lblTitle);
					horizontalPanel_3.setCellHorizontalAlignment(lblTitle, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_3.setCellWidth(lblTitle, "20%");					
					
					VerticalPanel verticalPanel_1 = new VerticalPanel();
					TreeItem descriptionTreeItem = new TreeItem(verticalPanel_1);
					addTreeItemAndSetStyle(toDoTreeItem, descriptionTreeItem);
					verticalPanel_1.setWidth("100%");
					
					/*Label lblDescriptionText = new Label("Description:");
					verticalPanel_1.add(lblDescriptionText);
					lblDescriptionText.setSize("89px", "30px");*/
					
					Label lblDescription = new Label(toDoDTO.getDescription());
					lblDescription.getElement().getStyle().setProperty("whiteSpace", "pre");
					lblDescription.setWordWrap(true);
					verticalPanel_1.add(lblDescription);
					verticalPanel_1.setCellWidth(lblDescription, "100%");
					
					//VerticalPanel verticalPanel_2 = new VerticalPanel();
					//TreeItem evaluationTreeItem = new TreeItem(verticalPanel_2);
					TreeItem evaluationTreeItem = new TreeItem("Evaluation");
					evaluationTreeItem.setUserObject(toDoDTO);
					addTreeItemAndSetStyle(toDoTreeItem, evaluationTreeItem);
					//verticalPanel_2.setWidth("100%");
					
					//Label lblEvaluationText = new Label("Evaluation:");
					//verticalPanel_2.add(lblEvaluationText);
					//lblEvaluationText.setWidth("89px");
					
					VerticalPanel verticalPanel_3 = new VerticalPanel();
					TreeItem evaluationTextTreeItem = new TreeItem(verticalPanel_3);
					addTreeItemAndSetStyle(evaluationTreeItem, evaluationTextTreeItem);
					verticalPanel_3.setWidth("100%");
					verticalPanel_3.setSpacing(5);
					
					
					TreeItem logsTreeItem = new TreeItem("Logs");
					logsTreeItem.setUserObject(toDoDTO);
					addTreeItemAndSetStyle(toDoTreeItem, logsTreeItem);
					
					HorizontalPanel horizontalPanel_4 = new HorizontalPanel();
					horizontalPanel_4.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
					TreeItem logsHeaderTreeItem = new TreeItem(horizontalPanel_4);
					addTreeItemAndSetStyle(logsTreeItem, logsHeaderTreeItem);
					horizontalPanel_4.setSize("100%", "30px");
					horizontalPanel_4.setBorderWidth(1);
					
					Label lblLogDate = new Label("Log date");
					horizontalPanel_4.add(lblLogDate);
					horizontalPanel_4.setCellHorizontalAlignment(lblLogDate, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblLogDate, "33%");
					lblLogDate.setWidth("56px");
					
					Label lblWorkHour = new Label("Work hours");
					horizontalPanel_4.add(lblWorkHour);
					horizontalPanel_4.setCellHorizontalAlignment(lblWorkHour, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblWorkHour, "33%");
					lblWorkHour.setWidth("70px");
					
					Label lblFile = new Label("File");
					horizontalPanel_4.add(lblFile);
					horizontalPanel_4.setCellHorizontalAlignment(lblFile, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblFile, "33%");
					lblFile.setWidth("28px");			
					
					
					HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
					TreeItem modifyToDoTreeItem = new TreeItem(horizontalPanel_2);
					modifyToDoTreeItem.setUserObject(toDoDTO);
					addTreeItemAndSetStyle(toDoTreeItem, modifyToDoTreeItem);
					horizontalPanel_2.setWidth("100%");
					
					TreeItemButton btnModifyToDo = new TreeItemButton("Modify to-do");
					horizontalPanel_2.add(btnModifyToDo);
					btnModifyToDo.setParentTreeItem(modifyToDoTreeItem);
					if (userId != toDoDTO.getTutorId())
						btnModifyToDo.setEnabled(false);
					
					TreeItemButton btnDeleteToDo = new TreeItemButton("Delete to-do");
					horizontalPanel_2.add(btnDeleteToDo);
					btnDeleteToDo.setParentTreeItem(modifyToDoTreeItem);
					if (userId != toDoDTO.getTutorId())
						btnDeleteToDo.setEnabled(false);
					
					btnModifyToDo.addClickHandler(new ClickHandler() {
						
						@Override
						public void onClick(ClickEvent event) {
							TreeItemButton button = (TreeItemButton) event.getSource();
							
							TreeItem toDoTreeItem =  button.getParentTreeItem().getParentItem();
							toDoTreeItem.removeItems();
							
							ToDoDTO toDoDTO = (ToDoDTO) toDoTreeItem.getUserObject();
							
							FlexTable flexTable = new FlexTable();
							flexTable.setWidth("100%");

							Label lblNewLog = new Label("Modify to-do");
							flexTable.setWidget(0, 0, lblNewLog);
							lblNewLog.setWidth("77px");

							Label lblTitle = new Label("Title");
							flexTable.setWidget(1, 0, lblTitle);
							lblTitle.setWidth("77px");
							
							TextBox titleTextBox = new TextBox();
							flexTable.setWidget(1, 1, titleTextBox);
							titleTextBox.setWidth("100%");
							titleTextBox.setText(toDoDTO.getTitle());
							
							Label lblWeek = new Label("Week");
							flexTable.setWidget(2, 0, lblWeek);
							lblWeek.setWidth("77px");
							
							IntegerBox weekIntegerBox = new IntegerBox();
							flexTable.setWidget(2, 1, weekIntegerBox);
							weekIntegerBox.setWidth("100%");
							weekIntegerBox.setValue(toDoDTO.getWeek());
							
							Label lblDescription = new Label("Description");
							flexTable.setWidget(3, 0, lblDescription);
							lblDescription.setWidth("77px");
							
							TextArea descriptionTextArea = new TextArea();
							flexTable.setWidget(3, 1, descriptionTextArea);
							descriptionTextArea.setWidth("100%");
							descriptionTextArea.setText(toDoDTO.getDescription());
							
							TreeItemButton cancelButton = new TreeItemButton("Cancel");
							cancelButton.setParentTreeItem(toDoTreeItem);
							flexTable.setWidget(4, 0, cancelButton);
							
							cancelButton.addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									loadToDos(selectedTeamMemberUserId);
								}
							});
							
							TreeItemButton saveButton = new TreeItemButton("Save");
							saveButton.setParentTreeItem(toDoTreeItem);
							flexTable.setWidget(4, 1, saveButton);
							
							saveButton.addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									TreeItemButton button = (TreeItemButton) event.getSource();
									
									TreeItem toDoTreeItem =  button.getParentTreeItem();
									
									FlexTable flexTable = (FlexTable) toDoTreeItem.getWidget();
									TextBox titleTextBox = (TextBox) flexTable.getWidget(1, 1);
									IntegerBox weekIntegerBox = (IntegerBox) flexTable.getWidget(2, 1);
									TextArea descriptionTextArea = (TextArea) flexTable.getWidget(3, 1);
									
									ToDoDTO toDoDTO = (ToDoDTO) toDoTreeItem.getUserObject();
									
									toDoDTO.setDate(new Date());
									toDoDTO.setTitle(titleTextBox.getText());
									toDoDTO.setWeek(weekIntegerBox.getValue() != null ? weekIntegerBox.getValue() : 0);
									toDoDTO.setDescription(descriptionTextArea.getText());
									
									toDoService.updateToDo(toDoDTO, new AsyncCallback<Boolean>() {
										
										@Override
										public void onSuccess(Boolean result) {
											loadToDos(selectedTeamMemberUserId);
										}
										
										@Override
										public void onFailure(Throwable caught) {
											Window.alert("Remote Procedure Call - Failure");
											
										}
									});
									
								}
							});
							
							toDoTreeItem.setWidget(flexTable);														
							
						}
					});
					
					btnDeleteToDo.addClickHandler(new ClickHandler() {
						
						@Override
						public void onClick(ClickEvent event) {
							TreeItemButton button = (TreeItemButton) event.getSource();
							
							TreeItem modifyToDoTreeItem =  button.getParentTreeItem();
							
							ToDoDTO toDoDTO = (ToDoDTO) modifyToDoTreeItem.getUserObject();
														
							toDoService.deleteToDo(toDoDTO.getTodoId(), new AsyncCallback<Boolean>() {
								
								@Override
								public void onSuccess(Boolean result) {
									loadToDos(selectedTeamMemberUserId);
								}
								
								@Override
								public void onFailure(Throwable caught) {
									Window.alert("Remote Procedure Call - Failure");
								}
						
							
							});
						}
					});
					
				}
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");				
			}
		});
		
	}
	
	private void resetToDoTree() {
		toDoTree.removeItems();
		
		HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
		horizontalPanel_3.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		toDoTree.addItem(horizontalPanel_3);
		horizontalPanel_3.setSize("100%", "30px");
		horizontalPanel_3.setBorderWidth(1);
		
		Label lblWeek = new Label("Week");
		horizontalPanel_3.add(lblWeek);
		horizontalPanel_3.setCellHorizontalAlignment(lblWeek, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblWeek, "20%");
		lblWeek.setWidth("35px");
		
		Label lblStudent = new Label("Student");
		horizontalPanel_3.add(lblStudent);
		horizontalPanel_3.setCellHorizontalAlignment(lblStudent, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblStudent, "20%");
		lblStudent.setWidth("48px");
		
		Label lblTutor = new Label("Tutor");
		horizontalPanel_3.add(lblTutor);
		horizontalPanel_3.setCellHorizontalAlignment(lblTutor, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblTutor, "20%");
		lblTutor.setWidth("35px");
		
		Label lblDate = new Label("Date");
		horizontalPanel_3.add(lblDate);
		horizontalPanel_3.setCellHorizontalAlignment(lblDate, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblDate, "20%");
		lblDate.setWidth("31px");
		
		Label lblTitle = new Label("Title");
		horizontalPanel_3.add(lblTitle);
		horizontalPanel_3.setCellHorizontalAlignment(lblTitle, HasHorizontalAlignment.ALIGN_CENTER);
		horizontalPanel_3.setCellWidth(lblTitle, "20%");
		lblTitle.setWidth("29px");
		
		HorizontalPanel horizontalPanel_5 = new HorizontalPanel();
		horizontalPanel_5.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		TreeItem uploadToDoTreeItem = toDoTree.addItem(horizontalPanel_5);
		horizontalPanel_5.setSize("100%", "30px");
		
		TreeItemButton btnUploadNewToDo = new TreeItemButton("Upload new to-do");
		btnUploadNewToDo.setParentTreeItem(uploadToDoTreeItem);
		horizontalPanel_5.add(btnUploadNewToDo);
		
		btnUploadNewToDo.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				TreeItemButton button = (TreeItemButton) event.getSource();
				
				TreeItem uploadToDoTreeItem =  button.getParentTreeItem();
				uploadToDoTreeItem.removeItems();
													
				FlexTable flexTable = new FlexTable();
				flexTable.setWidth("100%");

				Label lblNewLog = new Label("New to-do");
				flexTable.setWidget(0, 0, lblNewLog);
				lblNewLog.setWidth("77px");

				Label lblTitle = new Label("Title");
				flexTable.setWidget(1, 0, lblTitle);
				lblTitle.setWidth("77px");
				
				TextBox titleTextBox = new TextBox();
				flexTable.setWidget(1, 1, titleTextBox);
				titleTextBox.setWidth("100%");
				
				Label lblWeek = new Label("Week");
				flexTable.setWidget(2, 0, lblWeek);
				lblWeek.setWidth("77px");
				
				IntegerBox weekIntegerBox = new IntegerBox();
				flexTable.setWidget(2, 1, weekIntegerBox);
				weekIntegerBox.setWidth("100%");
				
				Label lblDescription = new Label("Description");
				flexTable.setWidget(3, 0, lblDescription);
				lblDescription.setWidth("77px");
				
				TextArea descriptionTextArea = new TextArea();
				flexTable.setWidget(3, 1, descriptionTextArea);
				descriptionTextArea.setWidth("100%");
				
				TreeItemButton cancelButton = new TreeItemButton("Cancel");
				cancelButton.setParentTreeItem(uploadToDoTreeItem);
				flexTable.setWidget(4, 0, cancelButton);
				
				cancelButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						loadToDos(selectedTeamMemberUserId);
					}
				});
				
				TreeItemButton saveButton = new TreeItemButton("Save");
				saveButton.setParentTreeItem(uploadToDoTreeItem);
				flexTable.setWidget(4, 1, saveButton);
				
				saveButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						TreeItemButton button = (TreeItemButton) event.getSource();
						
						TreeItem uploadLogTreeItem =  button.getParentTreeItem();
						
						FlexTable flexTable = (FlexTable) uploadLogTreeItem.getWidget();
						TextBox titleTextBox = (TextBox) flexTable.getWidget(1, 1);
						IntegerBox weekIntegerBox = (IntegerBox) flexTable.getWidget(2, 1);
						TextArea descriptionTextArea = (TextArea) flexTable.getWidget(3, 1);
						
						ToDoDTO toDoDTO = new ToDoDTO();						
						toDoDTO.setStudentId(selectedTeamMemberUserId);						
						toDoDTO.setTutorId(userId);
						toDoDTO.setTeamId(selectedTeamId);
						toDoDTO.setDate(new Date());
						toDoDTO.setTitle(titleTextBox.getText());
						toDoDTO.setWeek(weekIntegerBox.getValue() != null ? weekIntegerBox.getValue() : 0);
						toDoDTO.setDescription(descriptionTextArea.getText());
						
						toDoService.createToDo(toDoDTO, new AsyncCallback<Boolean>() {
							
							@Override
							public void onSuccess(Boolean result) {
								loadToDos(selectedTeamMemberUserId);
							}
							
							@Override
							public void onFailure(Throwable caught) {
								Window.alert("Remote Procedure Call - Failure");
								
							}
						});
						
					}
				});
				
				uploadToDoTreeItem.setWidget(flexTable);						
				
			}
		});
	}
	
	private void loadEvaluation(TreeItem evaluationTreeitem) {
		ToDoDTO toDoDTO = (ToDoDTO)evaluationTreeitem.getUserObject();
    	
		evaluationTreeitem.removeItems();
    	VerticalPanel verticalPanel_3 = new VerticalPanel();
		TreeItem evaluationDetailsTreeItem = new TreeItem(verticalPanel_3);
		addTreeItemAndSetStyle(evaluationTreeitem, evaluationDetailsTreeItem);
		verticalPanel_3.setWidth("100%");
		verticalPanel_3.setSpacing(5);
    	
    	evaluationService.retrieveEvaluation(toDoDTO.getTodoId(), new AsyncCallback<EvaluationDTO>() {
			
			@Override
			public void onSuccess(EvaluationDTO result) {
				
				TreeItem toDoTreeItem = getToDoTreeItem(result.getToDoId());
				ToDoDTO toDoDTO = (ToDoDTO)toDoTreeItem.getUserObject();
				
				TreeItem evaluationDetailsTreeItem = toDoTreeItem.getChild(1).getChild(0);
				evaluationDetailsTreeItem.setUserObject(result);
				
				
				VerticalPanel verticalPanel = (VerticalPanel)evaluationDetailsTreeItem.getWidget();
				
				if (result.getEvaluationId() == 0) {
					HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_2);
					
					Label lblNoEvaluation = new Label("No evaluation yet from tutor!");
					lblNoEvaluation.getElement().getStyle().setProperty("whiteSpace", "pre");
					horizontalPanel_2.add(lblNoEvaluation);
					horizontalPanel_2.setCellWidth(lblNoEvaluation, "100%");
					
					HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_3);
					
					TreeItemButton btnUploadNewEvaluation = new TreeItemButton("Upload new evaluation");
					horizontalPanel_3.add(btnUploadNewEvaluation);
					horizontalPanel_3.setCellWidth(btnUploadNewEvaluation, "100%");
					btnUploadNewEvaluation.setParentTreeItem(evaluationDetailsTreeItem);
					if (userId != toDoDTO.getTutorId())
						btnUploadNewEvaluation.setEnabled(false);
					
					btnUploadNewEvaluation.addClickHandler(new ClickHandler() {
						
						@Override
						public void onClick(ClickEvent event) {
							TreeItemButton button = (TreeItemButton) event.getSource();
							
							TreeItem evaluationDetailsTreeItem =  button.getParentTreeItem();
							evaluationDetailsTreeItem.removeItems();
														
							FlexTable flexTable = new FlexTable();
							flexTable.setWidth("100%");

							Label lblNewLog = new Label("New evaluation");
							flexTable.setWidget(0, 0, lblNewLog);
							lblNewLog.setWidth("77px");
							
							Label lblDescription = new Label("Description");
							flexTable.setWidget(1, 0, lblDescription);
							lblDescription.setWidth("77px");
							
							TextArea descriptionTextArea = new TextArea();
							flexTable.setWidget(1, 1, descriptionTextArea);
							descriptionTextArea.setWidth("100%");
							
							TreeItemButton cancelButton = new TreeItemButton("Cancel");
							cancelButton.setParentTreeItem(evaluationDetailsTreeItem);
							flexTable.setWidget(2, 0, cancelButton);
							
							cancelButton.addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									TreeItemButton button = (TreeItemButton) event.getSource();
									
									TreeItem evaluationTreeitem =  button.getParentTreeItem().getParentItem();
									
									loadEvaluation(evaluationTreeitem);
								}
							});
							
							TreeItemButton saveButton = new TreeItemButton("Save");
							saveButton.setParentTreeItem(evaluationDetailsTreeItem);
							flexTable.setWidget(2, 1, saveButton);
							
							saveButton.addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									TreeItemButton button = (TreeItemButton) event.getSource();
									
									TreeItem evaluationDetailsTreeItem =  button.getParentTreeItem();
									
									FlexTable flexTable = (FlexTable) evaluationDetailsTreeItem.getWidget();
									TextArea descriptionTextArea = (TextArea) flexTable.getWidget(1, 1);
									
									EvaluationDTO evaluationDTO = (EvaluationDTO) evaluationDetailsTreeItem.getUserObject();
									
									evaluationDTO.setDate(new Date());
									evaluationDTO.setDescription(descriptionTextArea.getText());
									
									evaluationService.createEvaluation(evaluationDTO, new AsyncCallback<Long>() {
										
										@Override
										public void onSuccess(Long result) {
											TreeItem toDoTreeItem = getToDoTreeItem(result);
											if(toDoTreeItem != null) {
												loadEvaluation(toDoTreeItem.getChild(1));
											}
										}
										
										@Override
										public void onFailure(Throwable caught) {
											Window.alert("Remote Procedure Call - Failure");
											
										}
									});
									
								}
							});
							
							evaluationDetailsTreeItem.setWidget(flexTable);														
							
						}
					});
				}
				
				else {
				
					HorizontalPanel horizontalPanel_1 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_1);
					
					/*Label lblNewLabel_1 = new Label("Date:");
					horizontalPanel_1.add(lblNewLabel_1);
					lblNewLabel_1.setWidth("81px");*/
					
					Label lblDate = new Label(result.getDate().toString());
					horizontalPanel_1.add(lblDate);
					horizontalPanel_1.setCellWidth(lblDate, "100%");
					
					HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_2);
					
					/*Label label = new Label("Description:");
					horizontalPanel_2.add(label);
					label.setWidth("81px");*/
					
					Label lblDescription = new Label(result.getDescription());
					lblDescription.getElement().getStyle().setProperty("whiteSpace", "pre");
					lblDescription.setWordWrap(true);
					horizontalPanel_2.add(lblDescription);
					horizontalPanel_2.setCellWidth(lblDescription, "100%");
					
					HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_3);
					horizontalPanel_3.setWidth("100%");
					
					TreeItemButton btnModifyEvaluation = new TreeItemButton("Modify evaluation");
					horizontalPanel_3.add(btnModifyEvaluation);
					btnModifyEvaluation.setParentTreeItem(evaluationDetailsTreeItem);
					if (userId != toDoDTO.getTutorId())
						btnModifyEvaluation.setEnabled(false);
					
					TreeItemButton btnDeleteEvaluation = new TreeItemButton("Delete evaluation");
					horizontalPanel_3.add(btnDeleteEvaluation);
					btnDeleteEvaluation.setParentTreeItem(evaluationDetailsTreeItem);
					if (userId != toDoDTO.getTutorId())
						btnDeleteEvaluation.setEnabled(false);
					
					btnModifyEvaluation.addClickHandler(new ClickHandler() {
						
						@Override
						public void onClick(ClickEvent event) {
							TreeItemButton button = (TreeItemButton) event.getSource();
							
							TreeItem evaluationDetailsTreeItem =  button.getParentTreeItem();
							evaluationDetailsTreeItem.removeItems();
							
							EvaluationDTO evaluationDTO = (EvaluationDTO) evaluationDetailsTreeItem.getUserObject();
							
							FlexTable flexTable = new FlexTable();
							flexTable.setWidth("100%");

							Label lblNewLog = new Label("Modify evaluation");
							flexTable.setWidget(0, 0, lblNewLog);
							lblNewLog.setWidth("77px");
							
							Label lblDescription = new Label("Description");
							flexTable.setWidget(1, 0, lblDescription);
							lblDescription.setWidth("77px");
							
							TextArea descriptionTextArea = new TextArea();
							flexTable.setWidget(1, 1, descriptionTextArea);
							descriptionTextArea.setWidth("100%");
							descriptionTextArea.setText(evaluationDTO.getDescription());
							
							TreeItemButton cancelButton = new TreeItemButton("Cancel");
							cancelButton.setParentTreeItem(evaluationDetailsTreeItem);
							flexTable.setWidget(2, 0, cancelButton);
							
							cancelButton.addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									TreeItemButton button = (TreeItemButton) event.getSource();
									
									TreeItem evaluationTreeitem =  button.getParentTreeItem().getParentItem();
									
									loadEvaluation(evaluationTreeitem);
								}
							});
							
							TreeItemButton saveButton = new TreeItemButton("Save");
							saveButton.setParentTreeItem(evaluationDetailsTreeItem);
							flexTable.setWidget(2, 1, saveButton);
							
							saveButton.addClickHandler(new ClickHandler() {
								
								@Override
								public void onClick(ClickEvent event) {
									TreeItemButton button = (TreeItemButton) event.getSource();
									
									TreeItem evaluationDetailsTreeItem =  button.getParentTreeItem();
									
									FlexTable flexTable = (FlexTable) evaluationDetailsTreeItem.getWidget();
									TextArea descriptionTextArea = (TextArea) flexTable.getWidget(1, 1);
									
									EvaluationDTO evaluationDTO = (EvaluationDTO) evaluationDetailsTreeItem.getUserObject();
									
									evaluationDTO.setDate(new Date());
									evaluationDTO.setDescription(descriptionTextArea.getText());
									
									evaluationService.updateEvaluation(evaluationDTO, new AsyncCallback<Long>() {
										
										@Override
										public void onSuccess(Long result) {
											TreeItem toDoTreeItem = getToDoTreeItem(result);
											if(toDoTreeItem != null) {
												loadEvaluation(toDoTreeItem.getChild(1));
											}
										}
										
										@Override
										public void onFailure(Throwable caught) {
											Window.alert("Remote Procedure Call - Failure");
											
										}
									});
									
								}
							});
							
							evaluationDetailsTreeItem.setWidget(flexTable);														
							
						}
					});
					
					btnDeleteEvaluation.addClickHandler(new ClickHandler() {
						
						@Override
						public void onClick(ClickEvent event) {
							TreeItemButton button = (TreeItemButton) event.getSource();
							
							TreeItem evaluationDetailsTreeItem =  button.getParentTreeItem();
							
							EvaluationDTO evaluationDTO = (EvaluationDTO) evaluationDetailsTreeItem.getUserObject();
														
							evaluationService.deleteEvaluation(evaluationDTO.getEvaluationId(), new AsyncCallback<Long>() {
								
								@Override
								public void onSuccess(Long result) {
									TreeItem toDoTreeItem = getToDoTreeItem(result);
									if(toDoTreeItem != null) {
										loadEvaluation(toDoTreeItem.getChild(1));
									}
								}
								
								@Override
								public void onFailure(Throwable caught) {
									Window.alert("Remote Procedure Call - Failure");
								}
						
							
							});
						}
					});
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");											
			}
		});
    	
		
    }
	
	private void loadLogs(TreeItem logsTreeItem) {
		
		
		while (logsTreeItem.getChildCount() > 1) {
			logsTreeItem.removeItem(logsTreeItem.getChild(1));
		}

		ToDoDTO toDoDTO = (ToDoDTO)logsTreeItem.getUserObject();
		
		logService.retrieveLogs(toDoDTO.getTodoId(), new AsyncCallback<List<LogDTO>>() {

			@Override
			public void onSuccess(List<LogDTO> result) {
				if (result == null || result.size() == 0) {
					return;
				}
				
				TreeItem toDoTreeItem = getToDoTreeItem(result.get(0).getToDoId());
				
				TreeItem logsTreeItem = toDoTreeItem.getChild(2);
				
				for (LogDTO logDTO : result) {
					
					HorizontalPanel horizontalPanel_4 = new HorizontalPanel();
					horizontalPanel_4.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
					TreeItem logTreeItem = new TreeItem(horizontalPanel_4);
					logTreeItem.setUserObject(logDTO);
					addTreeItemAndSetStyle(logsTreeItem, logTreeItem);
					horizontalPanel_4.setSize("100%", "30px");
					
					Label lblLogDate = new Label(logDTO.getDate().toString());
					horizontalPanel_4.add(lblLogDate);
					horizontalPanel_4.setCellHorizontalAlignment(lblLogDate, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblLogDate, "33%");
					
					Label lblWorkHour = new Label(String.valueOf(logDTO.getWorkHour()));
					horizontalPanel_4.add(lblWorkHour);
					horizontalPanel_4.setCellHorizontalAlignment(lblWorkHour, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(lblWorkHour, "33%");
					
					TreeItemButton fileDownloadButton = new TreeItemButton("Download attached file");
					fileDownloadButton.setParentTreeItem(logTreeItem);
					horizontalPanel_4.add(fileDownloadButton);
					horizontalPanel_4.setCellHorizontalAlignment(fileDownloadButton, HasHorizontalAlignment.ALIGN_CENTER);
					horizontalPanel_4.setCellWidth(fileDownloadButton, "33%");

					if (logDTO.getAttachedFileName() == null || logDTO.getAttachedFileName().isEmpty())
						fileDownloadButton.setEnabled(false);
					fileDownloadButton.addClickHandler(downloadButtonClickHandler);
					
					
					
					VerticalPanel verticalPanel = new VerticalPanel();
					TreeItem logDetailsTreeItem = new TreeItem(verticalPanel);
					logDetailsTreeItem.setUserObject(logDTO);
					addTreeItemAndSetStyle(logTreeItem, logDetailsTreeItem);
					verticalPanel.setWidth("100%");
					verticalPanel.setSpacing(10);
					
					HorizontalPanel horizontalPanel_1 = new HorizontalPanel();
					verticalPanel.add(horizontalPanel_1);
					
					Label lblDescription = new Label(logDTO.getDescription());
					lblDescription.getElement().getStyle().setProperty("whiteSpace", "pre");
					lblDescription.setWordWrap(true);
					horizontalPanel_1.add(lblDescription);
					horizontalPanel_1.setCellWidth(lblDescription, "100%");
									
				}
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Remote Procedure Call - Failure");											
			}
		});
	}
	
	private ClickHandler downloadButtonClickHandler = new ClickHandler() {
		
		@Override
		public void onClick(ClickEvent event) {
			TreeItemButton button = (TreeItemButton) event.getSource();

			TreeItem logTreeItem =  button.getParentTreeItem();
			LogDTO logDTO = (LogDTO) logTreeItem.getUserObject();
			
			Window.open("/consulttime/logfiledownload?logid="+logDTO.getLogId(), "_blank", null);
			
		}
	};
	
	private void addTreeItemAndSetStyle(TreeItem parent, TreeItem child) {
		parent.addItem(child);

		Element div = parent.getElement();
		Element table = DOM.getFirstChild(div);
		Element tbody = DOM.getFirstChild(table);
		Element tr = DOM.getFirstChild(tbody);
		Element td = DOM.getChild(tr, 1);
		td.getStyle().setWidth(100, Unit.PCT);
	}
	
	private TreeItem getToDoTreeItem(long toDoId) {
		for (int i = 2, count = toDoTree.getItemCount(); i < count; i++) {
			TreeItem treeItem = toDoTree.getItem(i);
			ToDoDTO toDoDTO = (ToDoDTO)treeItem.getUserObject();
			if (toDoId == toDoDTO.getTodoId()) {
				return treeItem;
			}
		}
		return null;
	}
	
}
